package cn.bugstack.mybatis.session.defaults;

import cn.bugstack.mybatis.executor.Executor;
import cn.bugstack.mybatis.mapping.MappedStatement;
import cn.bugstack.mybatis.session.Configuration;
import cn.bugstack.mybatis.session.SqlSession;

import java.lang.reflect.Method;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 小傅哥，微信：fustack
 * @description 默认SqlSession实现类
 * @date 2022/04/01
 * @github https://github.com/fuzhengwei
 * @copyright 公众号：bugstack虫洞栈 | 博客：https://bugstack.cn - 沉淀、分享、成长，让自己和他人都能有所收获！
 */
public class DefaultSqlSession implements SqlSession {

    private Configuration configuration;
    private Executor executor;

    public DefaultSqlSession(Configuration configuration,Executor executor) {
        this.configuration = configuration;
        this.executor = executor;
    }

    @Override
    public <T> T selectOne(String statement) {
        return (T) ("你被代理了！" + statement);
    }

    @Override
    public <T> T selectOne(String statement, Object parameter) {
        try {
            MappedStatement ms = configuration.getMappedStatement(statement);
            List<T> list = executor.query(ms, parameter, Executor.NO_RESULT_HANDLER, ms.getBoundSql());
            return list.get(0);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }finally {

        }
    }

    private <T> List<T> resultSet2Obj(ResultSet resultSet, Class clazz) {
        List<T> list = new ArrayList<T>();
        try {
            ResultSetMetaData rmsd = resultSet.getMetaData();
            int columnCount = rmsd.getColumnCount();
            while (resultSet.next()){
                T obj = (T) clazz.newInstance();
                for (int i = 1; i <= columnCount; i++) {
                    Object value = resultSet.getObject(i);
                    String columnName = rmsd.getColumnName(i);
                    String methodName = "set"+columnName.substring(0,1).toUpperCase()+columnName.substring(1);
                    Method method;
                    if(value instanceof Timestamp){
                        method = clazz.getMethod(methodName,java.util.Date.class);
                    }else{
                        method = clazz.getMethod(methodName,value.getClass());
                    }
                    method.invoke(obj,value);
                }
                list.add(obj);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return list;
    }

    @Override
    public <T> T getMapper(Class<T> type) {
        return configuration.getMapper(type, this);
    }

    public Configuration getConfiguration() {
        return configuration;
    }

}
